Skip to content

Sync upstream Doubao Coding Plan usage#45

Merged
ColumbusLabs merged 2 commits into
mainfrom
codex/upstream-sync-doubao-coding-plan-20260702
Jul 2, 2026
Merged

Sync upstream Doubao Coding Plan usage#45
ColumbusLabs merged 2 commits into
mainfrom
codex/upstream-sync-doubao-coding-plan-20260702

Conversation

@ColumbusLabs

Copy link
Copy Markdown
Owner

Summary

  • Sync Pete upstream tail 0a18391e1838ee9d110395f3409f785bfbca7c99..44f0949b6b0503f88fc69ae8d3aaac4f4f53f739 (feat: add Doubao Coding Plan usage (#1841)).
  • Add Doubao signed Volcengine AK/SK support for session, weekly, and monthly Coding Plan usage.
  • Preserve QuotaKit-owned config/copy by keeping ~/.quotakit/config.json, QuotaKit changelog style, build numbers, and shipped version tracking unchanged while advancing UPSTREAM_MONITOR_BASE.

Reviewed risk areas

  • Doubao request signing, quota parsing, Ark fallback, error parsing, and credential precedence.
  • Provider settings/config validation and incomplete AK/SK handling.
  • Menu and widget rate-window labels with existing QuotaKit helper logic preserved.
  • Branding/release metadata and mobile/widget generic sync exposure.

Validation

  • git diff --cached --check
  • swift test --no-parallel --filter 'DoubaoProviderTests|DoubaoUsageFetcherTests|ProviderConfigEnvironmentTests|ConfigValidationTests|MenuDescriptorCrossModelTests|StatusItemBalanceDisplayTests' (127 tests)\n- swift build\n- PARSER_LINT_BASE=origin/main ./Scripts/lint.sh lint\n\nLive Doubao AK/SK validation was not run because repository rules require explicit approval for live provider/account probes.

steipete and others added 2 commits July 2, 2026 07:45
* fix(sakana): parse weekly/5-hour reset time as UTC, not device-local

console.sakana.ai/billing always server-renders "Resets on <date>" in
UTC (confirmed via the raw HTML's embedded "timeZone":"UTC" hydration
payload marker, and Sakana's own "Weekly usage resets every Monday at
00:00 UTC" copy elsewhere on the page). The browser only corrects that
text to the viewer's local timezone client-side, after JS hydration --
which this HTML-only fetcher never runs.

SakanaUsageFetcher.parseResetDate parsed the raw string using
TimeZone.current instead, so every non-UTC user got a reset time off
by exactly their UTC offset -- 5.5h early on an IST machine, verified
by building main into the codexbar CLI and running it against a real
account: the tool's own JSON output landed 5.5h before the true reset
instant shown in a browser on the same page at the same moment.

Removes the timeZone parameter entirely (it no longer has a legitimate
caller-supplied value; the source data is always UTC) and hardcodes
UTC in parseResetDate. Updates the existing fixture-based tests, which
previously asserted the buggy local-timezone interpretation as if it
were correct, and adds a regression test pinned to a literal Unix
timestamp independent of the date-building helper.

Fixes #1826.

* address clawsweeper review: strengthen regression test, fix stale docs

- The UTC regression test didn't actually pin the fix: on a UTC CI
  runner, the pre-fix TimeZone.current code would coincidentally
  still produce the correct instant, so the test would pass either
  way. Force NSTimeZone.default to UTC+14 for the test's duration
  (same pattern as BedrockUsageStatsTests) so it only passes when the
  parser genuinely ignores the device timezone. Verified by
  temporarily reverting the fix locally and confirming the test now
  fails with the expected 5.5h-off result before restoring it.
- docs/sakana.md still said reset dates use the device's local time
  zone (TimeZone.current) -- exactly the behavior this PR removes.
  Updated to describe the actual UTC parsing and why, linking #1826.

* test(sakana): serialize suite with process-global timezone mutation

clawsweeper's re-review flagged that the new NSTimeZone.default
override test lives in a non-serialized suite, unlike the existing
BedrockUsageStatsTests that uses the same pattern -- unrelated
parallel Swift Testing cases could observe UTC+14 and fail
nondeterministically. Mark @suite(.serialized), matching Bedrock's
precedent exactly.

* Localize provider menu strings

Move remaining provider UI copy through localization helpers and add Traditional Chinese translations.

Preserve existing personal-info redaction behavior while localizing the visible placeholders and usage labels.

* fix(codex): keep cached error envelopes parseable

Keep stored OpenAI dashboard and Codex credits cached failure envelopes in English so CodexUIErrorMapper can parse the Cached values from marker.

Add zh-Hant regression coverage for localized user-facing cached error messages.

* fix(claude): localize Claude Code sign-in action

Route the Claude Code sign-in menu label through localization and add English, zh-Hant, and strict-locale catalog entries.

Add a zh-Hant regression test for the Claude account action.

* fix(localization): complete Claude sign-in catalog parity

Add the Claude Code sign-in label to localization catalogs covered by strict parity tests so CI passes after the menu action was localized.

* Add CrossModel provider

CrossModel (https://crossmodel.ai) is a multi-provider, OpenAI- and
Anthropic-compatible API aggregation platform billed against a prepaid
USD wallet. This adds it as an API-key usage provider, modeled on the
OpenRouter provider since the data shape is nearly identical (wallet
balance + daily/weekly/monthly spend).

Data source (two read-only endpoints, integer micro units):
- GET /v1/credits -> balance_micro, uncollected_micro
- GET /v1/usage   -> daily/weekly/monthly cost_micro + tokens + counts

Display: balance in the identity line (and optional menu bar), today/
this week/this month spend in the menu card, and a shared inline
dashboard. No quota meter (prepaid wallet, no per-key limit).

Auth: CROSSMODEL_API_KEY env var or Settings/CLI config. Base URL
override via CROSSMODEL_API_URL (loopback HTTP allowed for local
testing).

Tests: CrossModelUsageStatsTests (decode, micro->USD, best-effort
usage, 401, redaction, round-trip) and a ProviderConfigEnvironment
regression covering Settings/CLI-saved keys.

* Fix CrossModel menu metrics and diagnostics

* fix: harden CrossModel provider integration

* fix: suppress generic credits bar for CrossModel menu card

CrossModel's balance lives in crossModelUsage, not the generic
credits path, so the fallback creditsHint text ("Wallet balance
from the CrossModel API") rendered as a misleading Credits row.
Suppress it the same way OpenRouter's balance-only card does.

* fix: repair CrossModel currency handling

* fix: normalize CrossModel redirect ports

* docs: update CrossModel provider count

* fix: respect CrossModel optional usage setting

* fix: render CrossModel CLI usage

* docs: note Sakana reset timezone fix

* test: align Sakana fixture with raw UTC HTML

* fix: preserve hidden identity behavior

* docs: note localization completion

* fix: preserve CrossModel balance without usage

* feat: add Doubao Coding Plan usage

Co-authored-by: LeoLin <leolin990405@gmail.com>

* fix: expose CrossModel diagnostics

---------

Co-authored-by: ss251 <ss251@uw.edu>
Co-authored-by: Shun Min Chang <ji394m6y7@gmail.com>
Co-authored-by: hujuncheng <juncheng233@hotmail.com>
Co-authored-by: LeoLin <leolin990405@gmail.com>
# Conflicts:
#	CHANGELOG.md
#	Sources/CodexBar/MenuDescriptor.swift
#	Sources/CodexBar/Providers/Doubao/DoubaoProviderImplementation.swift
#	Sources/CodexBar/UsageStore+WidgetSnapshot.swift
@ColumbusLabs ColumbusLabs merged commit 6c6fa2c into main Jul 2, 2026
10 checks passed
@ColumbusLabs ColumbusLabs deleted the codex/upstream-sync-doubao-coding-plan-20260702 branch July 2, 2026 16:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants